<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */

namespace app\service\fetch\ocean;

use app\enum\CommonEnum;
use app\enum\ConfigEnum;
use app\enum\OceanEnum;
use app\model\ClientAccountModel;
use app\model\KsActionBarModel;
use app\model\OeAssetsModel;
use app\model\OeOptimizedGoalNewModel;
use app\model\OeVideoModel;
use app\service\client\AccountService;
use app\service\fetch\MediaInterface;
use app\service\fetch\MediaService;
use app\service\ocean\AdvertiserService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Model;

class OptimizedGoalService extends MediaService implements MediaInterface
{

    /**
     * 同步可用优化目标（巨量广告升级版）列表.
     * @param string $advertiserId 广告主id
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getOptimizedGoal(string $advertiserId = ''): bool
    {
        $appPromotionType = OceanEnum::APP_PROMOTION_TYPE;
        // 获取账户信息
        $obj = AccountService::getAccountModel(0, $advertiserId);
        if (! $obj instanceof ClientAccountModel || ! $obj->getKey()) {
            return self::setError('账户数据不存在');
        }

        // 获取资产信息
        $assetsData = OeAssetsModel::where('advertiser_id', $advertiserId)->select()->toArray();
        if (empty($assetsData)) {
            return self::setError('资产信息不存在');
        }
        $params = [];
        foreach ($assetsData as $assets) {
            if ($assets['asset_type'] == 'APP') {
                $assetArr = json_decode($assets['app'], true);
                $param = [
                    'landing_type' => 'APP',
                    'ad_type' => 'ALL',
                    'asset_type' => 'APP',
                ];
            } elseif ($assets['asset_type'] == 'THIRD_EXTERNAL') {
                $assetArr = json_decode($assets['landing_pages'], true);
                $param = [
                    'landing_type' => 'LINK',
                    'ad_type' => 'ALL',
                    'asset_type' => 'THIRDPARTY',
                ];
            }
            if (! empty($assetArr)) {
                foreach ($assetArr as $asset) {
                    $param['asset_id'] = $asset['asset_id'];
                    if ($assets['asset_type'] == 'APP') {
                        foreach ($appPromotionType as $type) {
                            $param['app_type'] = $asset['app_type'];
                            $param['app_promotion_type'] = $type;
                            $params[] = $param;
                        }
                    } else {
                        $params[] = $param;
                    }
                }
            }
        }
        if (empty($params)) {
            return self::setError('请求参数不存在');
        }
        foreach ($params as $param) {
            // 请求接口
            $result = self::getList($advertiserId, $param);
            if ($result === false) {
                return false;
            }
            if (count($result['data']['goals']) == 0) {
                break;
            }
            foreach ($result['data']['goals'] as $item) {
                $item['asset_id'] = $param['asset_id'];
                $item['asset_type'] = $param['asset_type'];
                $item['landing_type'] = $param['landing_type'];
                $item['ad_type'] = $param['ad_type'];
                $item['app_type'] = ! empty($param['app_type']) ? $param['app_type'] : '';
                $item['app_promotion_type'] = ! empty($param['app_promotion_type']) ? $param['app_promotion_type'] : '';
                $model = self::getInfo($advertiserId, $item);
                if (! $model instanceof OeOptimizedGoalNewModel || ! $model->getKey()) {
                    $model = new OeOptimizedGoalNewModel();
                }
                $model->setAttrs([
                    'advertiser_id' => $advertiserId,
                    'account_id' => $obj->getKey(),
                    'landing_type' => $item['landing_type'],
                    'ad_type' => $item['ad_type'],
                    'asset_type' => $item['asset_type'],
                    'app_type' => $item['app_type'],
                    'app_promotion_type' => $item['app_promotion_type'],
                    'asset_id' => $param['asset_id'],
                    'external_action' => $item['external_action'],
                    'optimization_name' => $item['optimization_name'],
                    'history_back' => $item['history_back'],
                    'twenty_four_hour_back' => $item['twenty_four_hour_back'],
                    'deep_goals' => ! empty($item['deep_goals']) ? json_encode($item['deep_goals'], JSON_UNESCAPED_UNICODE) : json_encode([], JSON_UNESCAPED_UNICODE),
                ]);
                if (! $model->save()) {
                    return self::setError('保存数据出错');
                }
            }
        }
        return true;
    }

    /**
     * 拉取信息.
     *
     * @param string $advertiserId 账户id
     * @return bool|mixed|string
     */
    private static function getList(string $advertiserId = '', array $params = [])
    {
        $token = AccountService::getToken(CommonEnum::OE_MEDIA, $advertiserId);
        if (! $token) {
            return self::setError('token获取失败');
        }
        $headers = [
            'Access-Token' => $token,
            'Content-Type' => 'application/json',
        ];
        $params['advertiser_id'] = $advertiserId;
        return AdvertiserService::getOptimizedGoal($headers, $params);
    }

    /**
     * 获取视频信息.
     *
     * @param string $advertiserId 账户id
     * @param array $item
     * @return null|array|mixed|Model|OeVideoModel
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private static function getInfo(string $advertiserId = '', array $item = [])
    {
        $where = [
            ['advertiser_id', '=', $advertiserId],
            ['asset_id', '=', $item['asset_id']],
            ['landing_type', '=', $item['landing_type']],
            ['asset_type', '=', $item['asset_type']],
            ['external_action', '=', $item['external_action']],
            ['app_type', '=', $item['app_type']],
            ['app_promotion_type', '=', $item['app_promotion_type'] ?? ''],
        ];

        return (new OeOptimizedGoalNewModel())->where($where)->field(true)->find();
    }
}
